﻿using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Persistencia_y_capa_de_negocio;
using System.Collections;
using System.Text.RegularExpressions;
namespace clonegame
{
    /// <summary>
    /// Formulario para editar y consultar usuarios.
    /// </summary>
    public partial class formularioUsuarioEditar : UserControl
    {

        /// <summary>
        /// Representa una instancia de la clase. De esta forma trabajare
        /// Siempre con el mismo formulario
        /// </summary>
        private static readonly formularioUsuarioEditar instancia = new formularioUsuarioEditar();
        /// <summary>
        /// Representa la id del usuario mostrado en el momento actual. Si es una
        /// inserción valdra -1.
        /// </summary>
        private int IDusuarioMostrado;
        /// <summary>
        /// Lo uso para controlar errores en la introcción de campos para la
        /// busqueda y la edición
        /// </summary>
        private ErrorProvider errorCampo;
        /// <summary>
        /// Me sirve para saber cuando ha sido cargada una imagen en el pbAvatar
        /// </summary>
        private bool imagenCargada;
        /// <summary>
        /// Representa la contraseña codificada del ultimo usuario cargado.
        /// </summary>
        private string PassUsuarioMostrado;
        
        /// <summary>
        /// Obtiene la instancia del formulario.De esta forma trabajare
        /// siempre con el mismo formulario
        /// </summary>
        public static formularioUsuarioEditar Instancia
        {
            get { return instancia; }
        }

        /// <summary>
        /// Constructor por defecto del formulario.
        /// </summary>
        public formularioUsuarioEditar()
        {
            InitializeComponent();

            //Inicialmente estoy en consultas y busquedas
            ModoBusqueda();

            errorCampo = new ErrorProvider();
            imagenCargada = false;
        }

        /// <summary>
        /// Permite cargar los datos de un usuario en los distintos campos del formulario
        /// </summary>
        /// <param name="cuenta">Nombre del usuario</param>
        /// <param name="pass">Contraseña del usuario</param>
        /// <param name="correo">E-Mail del usuario</param>
        /// <param name="fReg">Fecha de registro del usuario</param>
        /// <param name="coorXBase">Cooordenada x de la base del usuario</param>
        /// <param name="coorYBase">Cooordenada y de la base del usuario</param>
        /// <param name="coorXCuad">Cooordenada x del cuadrante del usuario</param>
        /// <param name="coorYCuad">Cooordenada x del cuadrante del usuario</param>
        /// <param name="idUsuario">Id del usuario</param>
        public void cargarDatosUsuario(string cuenta, string pass, string correo, DateTime fReg, int coorXBase, int coorYBase, 
            int coorXCuad, int coorYCuad, int idUsuario)
        {
            IDusuarioMostrado = idUsuario;
            tbNick.Text = cuenta;
            PassUsuarioMostrado = pass; 
            //No muestro la contaseña ya que como está codificada no es importante.
            tbEmail.Text = correo;
            dtpFechaRegistro.Value = fReg.Date;
            nudBaseX.Value = coorXBase;
            nudBaseY.Value = coorYBase;
            nudCuadX.Value = coorXCuad;
            nudCuadY.Value = coorYCuad;

            //Aqui direccion de las imagenes.
            string mdf = Application.ExecutablePath;
            mdf = mdf.Remove(mdf.LastIndexOf(@"\bin\"));

            string mdf2 = mdf.Remove(mdf.LastIndexOf(@"\clonegame"));
            mdf2 += @"\clonegame\imagenes\usuarios\";
            try
            {
                pbAvatar.Image = System.Drawing.Image.FromFile(mdf2 + cuenta + ".png");
            }
            catch (Exception)
            {
                pbAvatar.Image = clonegame.Properties.Resources.ImgNoEncontrada;
            }
            //Ahora llamar a la funcion RellenaDGVEdificos para rellenar el DGV con Edificios.
            RellenaDGVEdificios(true, idUsuario, false);

            //Lo mismo para las unidades
            RellenaDGVUnidades(true, idUsuario, false);


        }

        /// <summary>
        /// Permite mostrar los datos de las Unidades del usuario en el Data Grid View
        /// dgvUnidades de la pagina de unidades del usuario
        /// </summary>
        /// <param name="todos">Si es true se muestran todos las unidades del usuario</param>
        /// <param name="idUsuario">Id del usuario</param>
        /// <param name="nuevo">True si hay que vaciar el dgv previamente.</param>
        public void RellenaDGVUnidades(bool todos, int idUsuario, bool nuevo)
        {
            if (nuevo)
            {
                dgvUnidadesUsuario.Rows.Clear();
            }
            //Ruta de las imagenes de las unidades
            string mdf = Application.ExecutablePath;
            mdf = mdf.Remove(mdf.LastIndexOf(@"\bin\"));

            string mdf2 = mdf.Remove(mdf.LastIndexOf(@"\clonegame"));
            mdf2 += @"\clonegame\imagenes\unidades\";

            int numFilas = 0;
            int i = 0;
            ArrayList UnidadesUsuario = CADUnidadesUsuario.Instancia.obtenerUnidadesUsuario(idUsuario);
            //Ahora ya tengo las unidades del usuario en una lista
            ArrayList Unidades = new ArrayList();
            if (todos)
            {
                //Obtengo a continuación la lista con todos los edificios disponibles.
                Unidades = CADUnidad.Instancia.getUnidades();
            }
            else
            {
                string nom, ataque, defensa, tiempo, velocidad, vida;
                nom = ataque = defensa = tiempo = velocidad = vida = "";
                nom = tbNombreUnidad.Text;
                if (nudAtaqueUnidad.Value != -1)
                {
                    ataque = nudAtaqueUnidad.Value.ToString();
                }
                if (nudDefensaUnidad.Value != -1)
                {
                    defensa = nudDefensaUnidad.Value.ToString();
                }
                if (nudVelocidadUnidad.Value != -1)
                {
                    velocidad = nudVelocidadUnidad.Value.ToString();
                }
                if (nudVidaUnidad.Value != -1)
                {
                    vida = nudVidaUnidad.Value.ToString();
                }
                if (nudTiempoUnidad.Value != -1)
                {
                    tiempo = nudTiempoUnidad.Value.ToString();
                }

                Unidades = CADUnidad.Instancia.getUnidadesBuscar(nom, vida, defensa, ataque, velocidad, tiempo);
                //MessageBox.Show("Se han encontrado " + Unidades.Count.ToString() + " unidades que coincidan con los criterio velocidad: " + velocidad);
            }

            foreach (ENUnidad uni in Unidades)
            {
                if (i == 0)
                {
                    if (uni != null)
                    {//Compruebo si hay alguna unidad en lista
                        //Completar informacion del formulario para el primero.
                        nudVelocidadUnidad.Maximum = 10000;
                        nudTiempoUnidad.Maximum = 10000;
                        tbNombreUnidad.Text = uni.Nombre;
                        nudTiempoUnidad.Value = uni.Tiempo;                      
                        nudVelocidadUnidad.Value = uni.Velocidad;
                        nudVidaUnidad.Value = uni.Vida;
                        nudAtaqueUnidad.Value = uni.Ataque;
                        nudDefensaUnidad.Value = uni.Defensa;
                    }
                }
                else
                {
                    //Puedo hacer un break y salir del bucle o mostrar un error
                }
                i++;
                dgvUnidadesUsuario.Rows.Add(1);//añadimos una fila vacia al dgv
                //Campo Imagene
                try
                {
                    dgvUnidadesUsuario.Rows[numFilas].Cells[0].Value = System.Drawing.Image.FromFile(mdf2 + uni.Nombre + ".png");
                }
                catch (Exception)
                {
                    dgvUnidadesUsuario.Rows[numFilas].Cells[0].Value = clonegame.Properties.Resources.ImgNoEncontrada;

                }
                //Rellenamos los campos nombre. descripcion e id de la unidad.
                dgvUnidadesUsuario.Rows[numFilas].Cells[1].Value = uni.Nombre;
                dgvUnidadesUsuario.Rows[numFilas].Cells[2].Value = uni.Descripcion;
                dgvUnidadesUsuario.Rows[numFilas].Cells[5].Value=uni.Id;
                foreach (ENUnidadesUsuario un1 in UnidadesUsuario)
                {
                    if (uni.Id == un1.IDUnidad)
                    {//Si los id coinciden es xq el usuario tiene esa unidad.
                        //podria hacerlo con una select pero como tengo que marcar en el dgv un campo por cada uno
                        // que coincida no se si seria posible haciendo esto o seria mas pesado al final.
                        dgvUnidadesUsuario.Rows[numFilas].Cells[4].Value = true;
                        dgvUnidadesUsuario.Rows[numFilas].Cells[3].Value = un1.Cantidad;
                    }
                }
                numFilas++;

            }
        }




        /// <summary>
        /// Permite mostrar los datos de los Edificios del usuario en el Data Grid View
        /// dgvEdificios de la pagina de edificios del usuario
        /// </summary>
        /// <param name="todos">Si es true se muestran todos los edificios del usuario</param>
        /// <param name="idUsuario">Id del usuario</param>
        /// <param name="nuevo">True si hay que vaciar el dgv previamente.</param>
        public void RellenaDGVEdificios(bool todos, int idUsuario, bool nuevo) 
            {
                if (nuevo)
                {
                    dgvEdificios.Rows.Clear();
                }
                //Ruta de las imagenes de los edificios
                string mdf = Application.ExecutablePath;
                mdf = mdf.Remove(mdf.LastIndexOf(@"\bin\"));

                string mdf2 = mdf.Remove(mdf.LastIndexOf(@"\clonegame"));
                mdf2 += @"\clonegame\imagenes\edificios\";


                int numFilas=0;
                int i=0;
                ArrayList EdificiosUsuario = CADEdificioUsuario.Instancia.obtenerEdificiosUsuario(idUsuario);
                //Ahora ya tengo los edificios del usuario en una lista
                ArrayList Edificios = new ArrayList();
                //Dependiendo del parametro todos, se muestran todos los edificios si este parametro es true y sino se
                //muestran solo los que coincidadn con los criterios de busqueda.
                if (todos)
                {
                    //Obtengo a continuación la lista con todos los edificios disponibles.
                    Edificios = CADEdificio.Instancia.getEdificios();
                }
                else
                {
                    string nombre, defensa, ataque;
                    nombre = defensa = ataque = "";
                    int tipo;
                    tipo = -1;
                    nombre = tbNombreEdificio.Text.ToString();
                    if (nudDefensaEdificios.Value != -1)
                    {
                        defensa = nudDefensaEdificios.Value.ToString();
                    }
                    if (nudAtaqueEdificios.Value != -1)
                    {
                        ataque = nudAtaqueEdificios.Value.ToString();
                    }
                    tipo = cbTipoEdificio.SelectedIndex;
                    Edificios = CADEdificio.Instancia.getEdificiosBuscar(nombre, tipo, defensa, ataque, new ArrayList());
                    /*if (Edificios != null)
                    {
                        MessageBox.Show("Se han encontrado " + Edificios.Count.ToString() + " que coincidan con los criterios de busqueda");
                    }
                    */

                }

                foreach (ENEdificio ed1 in Edificios){
                    if(i==0){
                        if(ed1 != null){//Compruebo si hay algun edificio en lista
                            //Completar informacion del formulario para el primero.
                            tbNombreEdificio.Text = ed1.Nombre;
                            nudDefensaEdificios.Value = ed1.Defensa;
                            cbTipoEdificio.SelectedIndex = ed1.Tipo;
                            nudAtaqueEdificios.Value = ed1.Ataque;
                        }
                    }
                    else{
                        //Puedo hacer un break y salir del bucle o mostrar un error
                    }
                    i++;
                    dgvEdificios.Rows.Add(1);//añadimos una fila vacia al dgv
                    //Campo Imagene
                    try
                    {
                        dgvEdificios.Rows[numFilas].Cells[0].Value = System.Drawing.Image.FromFile(mdf2 + ed1.Nombre + ".png");
                    }
                    catch (Exception)
                    {
                        dgvEdificios.Rows[numFilas].Cells[0].Value = clonegame.Properties.Resources.ImgNoEncontrada;

                    }
                    //Rellenamos los campos nombre, descripcion e id.
                    dgvEdificios.Rows[numFilas].Cells[1].Value= ed1.Nombre;
                    dgvEdificios.Rows[numFilas].Cells[2].Value= ed1.Descripcion;
                    dgvEdificios.Rows[numFilas].Cells[5].Value=ed1.Id;
                    foreach ( EnEdificioUsuario edus1 in EdificiosUsuario){
                        if (edus1.IDEdificio == ed1.Id)
                        {//Si los id coinciden es xq el usuario tiene ese edificio.
                            //podria hacerlo con una select pero como tengo que marcar en el dgv un campo por cada uno
                            // que coincida no se si seria posible haciendo esto o seria mas pesado al final.
                            dgvEdificios.Rows[numFilas].Cells[3].Value = edus1.NivelEd;
                            dgvEdificios.Rows[numFilas].Cells[4].Value = true;
                        }
                    }
                    numFilas++;

               }
            }

        /// <summary>
        /// Permite limpiar el formulario que se corresponde con la página de datos
        /// del usuario.
        /// </summary>
        public void BorrarPaginaCliente()
        {
            dgvUnidadesUsuario.Rows.Clear();
            tbNick.Clear();
            tbContrasena.Clear();
            tbEmail.Clear();
            pbAvatar.Image = clonegame.Properties.Resources.ImgNoEncontrada;
            dtpFechaRegistro.Value = DateTime.Today;
            nudBaseX.Value = 0;
            nudBaseY.Value = 0;
            nudCuadX.Value = 0;
            nudCuadY.Value = 0;
            
        }
        /// <summary>
        /// Permite limpiar el formulario que se corresponde con la página de edificios
        /// del usuario.
        /// </summary>
        public void BorrarPaginaEdificios()
        {
            tbNombreEdificio.Clear();
            nudDefensaEdificios.Value = -1;
            cbTipoEdificio.SelectedIndex = -1;
            nudAtaqueEdificios.Value = -1;
            dgvEdificios.Rows.Clear();
            cbMostrarTodosEdificios.Checked = false;
        }

        /// <summary>
        /// Permite limpiar el formulario que se corresponde con la página de unidades
        /// del usuario.
        /// </summary>
        public void BorrarPaginaUnidades()
        {
            tbNombreUnidad.Clear();
            nudAtaqueUnidad.Value=-1;
            nudDefensaUnidad.Value=-1;
            nudTiempoUnidad.Value=-1;
            nudVelocidadUnidad.Value=-1;
            nudVidaUnidad.Value=-1;
            cbMostrarTodosUnidades.Checked = false;
            dgvUnidadesUsuario.Rows.Clear();
        }

        /// <summary>
        /// Permite activar y desactivar los controles necesarios para el modo de edición
        /// </summary>
        public void ModoEdicion()
        {
            tbNick.Enabled = true;
            btGuardarCliente.Enabled = true;
            btBuscarCliente.Enabled = false;
            btGuardarEdificios.Enabled = true;
            btBuscarEdificios.Enabled = false;
            btGuardarUnidades.Enabled = true;
            btBuscarUnidades.Enabled = false;
            gbBusquedaEdificios.Enabled = false;
            gbBusquedaUnidad.Enabled = false;

            //Permitimos que el checkbox de la celda 2 del dgv edificios sea editable.
            dgvEdificios.ReadOnly = false;
            dgvEdificios.Columns[0].ReadOnly = true;
            dgvEdificios.Columns[1].ReadOnly = true;
            dgvEdificios.Columns[2].ReadOnly = true;
            dgvEdificios.Columns[3].ReadOnly = false;
            dgvEdificios.Columns[4].ReadOnly = false;
            dgvEdificios.Columns[5].ReadOnly = true;

            dgvUnidadesUsuario.ReadOnly = false;
            dgvUnidadesUsuario.Columns[0].ReadOnly = true;
            dgvUnidadesUsuario.Columns[1].ReadOnly = true;
            dgvUnidadesUsuario.Columns[2].ReadOnly = true;
            dgvUnidadesUsuario.Columns[3].ReadOnly = false;
            dgvUnidadesUsuario.Columns[4].ReadOnly = false;
            dgvUnidadesUsuario.Columns[5].ReadOnly = true;

            btBuscarImagen.Enabled = true;


            tbContrasena.Enabled = true;
            dtpFechaRegistro.Enabled = false;
            nudCuadX.Enabled = true;
            nudCuadY.Enabled = true;

            //Desactivar CriteriosDeBusqueda en cliente.

            gbCriteriosBusquedaCliente.Enabled = false;
        }

        /// <summary>
        /// Permite activar y desactivar los controles necesarios para el modo de búsqueda.
        /// </summary>
        public void ModoBusqueda()
        {
            tbNick.Enabled = true;
            btGuardarCliente.Enabled = false;
            btBuscarCliente.Enabled = true;
            btGuardarEdificios.Enabled = false;
            btBuscarEdificios.Enabled = true;
            btGuardarUnidades.Enabled = false;
            btBuscarUnidades.Enabled = true;
            gbBusquedaEdificios.Enabled = true;
            gbBusquedaUnidad.Enabled = true;

            tbContrasena.Enabled = false;
            dtpFechaRegistro.Enabled = true;
            nudCuadX.Enabled = true;
            nudCuadY.Enabled = true;

            dgvEdificios.ReadOnly = true;
            dgvUnidadesUsuario.ReadOnly = true;
            btBuscarImagen.Enabled = false;

            gbCriteriosBusquedaCliente.Enabled = true;
        }

        /// <summary>
        /// Boton que permite limpiar el formulario usuario
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btRestablecerCliente_Click(object sender, EventArgs e)
        {
            BorrarPaginaCliente();
        }

        /// <summary>
        /// Boton que permite limpiar el formulario edificios
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btRestablecerEd_Click(object sender, EventArgs e)
        {
            BorrarPaginaEdificios();
        }

        /// <summary>
        /// Boton que permite activar el modo búsqueda
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btBusqueda_Click(object sender, EventArgs e)
        {
            ModoBusqueda();
        }

        /// <summary>
        /// Boton que permite activar el modo edición.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btEditar_Click(object sender, EventArgs e)
        {
            ModoEdicion();
        }

        /// <summary>
        /// Controla que al seleccionar una fila del dgv que contiene los edificios, se carguen los
        /// datos del mismo en el formulario de la pagina edificios.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvEdificios_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex >= 0)
            {
                //obtenemos el nombre del edificio
                string nombreEdificio = dgvEdificios.Rows[e.RowIndex].Cells[1].Value.ToString();

                ENEdificio ed1 = CADEdificio.Instancia.getEdificio(nombreEdificio);

                //Compruebo si el edificio existe.
                if (ed1 != null)
                {
                    //Completar la información del formulario.
                    tbNombreEdificio.Text = ed1.Nombre;
                    nudDefensaEdificios.Value = ed1.Defensa;
                    cbTipoEdificio.SelectedIndex = ed1.Tipo;
                    nudAtaqueEdificios.Value = ed1.Ataque;
                    //marcar la opcion añadido a usuario. O quitar esta opcion?¿
                }
                else
                {
                    //seria un error
                }
            }

        }

        /// <summary>
        /// Boton de busqueda de la página usuarios.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btBuscarCliente_Click(object sender, EventArgs e)
        {
            ArrayList resultadoBusqueda;

            //Comprobrar campos completados. Tener en cuenta posibles errores de formato.
            string nom, email, bx, by, cx, cy, fecha;
            nom = email = bx = by = cx = cy = fecha= "";//valores por defecto
            if (cbMostrarTodosUsuarios.Checked == false)
            {
                //Por cuenta
                if (cbPorNombre.Checked == true)
                {
                    nom = tbNick.Text.ToString();
                }
                //Por email
                if (cbPorEmail.Checked == true)
                {
                    email = tbEmail.Text.ToString();
                }
                //Por fecha.
                if (cbPorFecha.Checked == true)
                {
                    fecha = dtpFechaRegistro.Value.Date.ToString();
                }
                //Por Base
                if (cbPorBase.Checked == true)
                {
                    bx = nudBaseX.Value.ToString();
                    by = nudBaseY.Value.ToString();
                }
                //Por Cuadrante
                if (cbPorCuadrante.Checked == true)
                {
                    cx = nudCuadX.Value.ToString();
                    cy = nudCuadY.Value.ToString();
                }
                resultadoBusqueda = CADUsuario.Instancia.BuscarUsuariosPorCampos(nom, email, bx, by, cx , cy, fecha);
            }
            else
            {
                resultadoBusqueda = CADUsuario.Instancia.obtenerUsuarios();
            }

            formularioUsuarios.Instancia.RellenaDGVConBusqueda(resultadoBusqueda);


        }

        /// <summary>
        /// Controla que al seleccionar una fila del dgv que contiene las unidades, se carguen los
        /// datos del mismo en el formulario de la pagina unidades.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvUnidadesUsuario_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex >= 0)
            {
                //obtenemos el nombre del edificio
                string nombreUnidad = dgvUnidadesUsuario.Rows[e.RowIndex].Cells[1].Value.ToString();

                ENUnidad uni = CADUnidad.Instancia.getUnidad(nombreUnidad);

                //Compruebo si la unidad existe.
                if (uni!= null)
                {
                    //Completar la información del formulario.
                    tbNombreUnidad.Text = uni.Nombre;
                    nudTiempoUnidad.Value = uni.Tiempo;
                    nudVelocidadUnidad.Value = uni.Velocidad;
                    nudVidaUnidad.Value = uni.Vida;
                    nudAtaqueUnidad.Value = uni.Ataque;
                    nudDefensaUnidad.Value = uni.Defensa;
                    //marcar la opcion añadido a usuario. O quitar esta opcion?¿
                }
                else
                {
                    //seria un error
                }
            }
        }

        /// <summary>
        /// Boton para buscar edificios en la página de edificios
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btBuscarEdificios_Click(object sender, EventArgs e)
        {
            bool mostrarTodos=false;
            if (cbMostrarTodosEdificios.Checked == true)
            {
                mostrarTodos = true;
            }
            RellenaDGVEdificios(mostrarTodos, IDusuarioMostrado, true);

        }

        /// <summary>
        /// Boton para buscar unidades en la página de unidades
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btBuscarUnidades_Click(object sender, EventArgs e)
        {
            bool mostrarTodos = false;
            if (cbMostrarTodosUnidades.Checked == true)
            {
                mostrarTodos = true;
            }
            RellenaDGVUnidades(mostrarTodos, IDusuarioMostrado, true);
        }

        /// <summary>
        /// Boton para limpiar la página de unidades del usuario
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btRestablecerUnidades_Click(object sender, EventArgs e)
        {
            BorrarPaginaUnidades();

        }

        /// <summary>
        /// Esta función sirve para restablecer los formularios cuando se
        /// desea introducir un nuevo usuario.
        /// </summary>
        public void NuevoUsuario()
        {
            PassUsuarioMostrado = "";
            IDusuarioMostrado = -1;
            BorrarPaginaCliente();
            BorrarPaginaEdificios();
            RellenaDGVEdificios(true, IDusuarioMostrado, true);
            BorrarPaginaUnidades();
            RellenaDGVUnidades(true, IDusuarioMostrado, true);
            ModoEdicion();
            tbNick.Enabled = true;
        }

        /// <summary>
        /// Permite guardar los cambios en los datos de un usuario, o las modificaciones en el mismo.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btGuardarCliente_Click(object sender, EventArgs e)
        {
            //Comprobacion de errores
            errorCampo.SetError(tbNick,"");
            if (tbNick.Text == "")
            { //Compruebo si el campo nick esta vacio
                errorCampo.SetIconAlignment(tbNick, ErrorIconAlignment.MiddleRight);
                errorCampo.SetIconPadding(tbNick, 2);
                errorCampo.SetError(tbNick, "El campo Nickname no puede estar vacio");
            }
            else
            {
                if(CADUsuario.Instancia.ExisteElUsuario(tbNick.Text, IDusuarioMostrado)==true)
                {
                    errorCampo.SetIconAlignment(tbNick, ErrorIconAlignment.MiddleRight);
                    errorCampo.SetIconPadding(tbNick, 2);
                    errorCampo.SetError(tbNick, "El Nickname ya esta siendo usado por otro usuario");
                }
                else
                {
                    errorCampo.SetError(tbContrasena, "");
                    if (tbContrasena.Text == "" && PassUsuarioMostrado=="")
                    {
                        errorCampo.SetIconAlignment(tbContrasena, ErrorIconAlignment.MiddleRight);
                        errorCampo.SetIconPadding(tbContrasena, 2);
                        errorCampo.SetError(tbContrasena, "El campo Contraseña no puede estar vacio");
                    }
                    else
                    {
                        errorCampo.SetError(tbEmail, "");
                        if (EmailEsValido(tbEmail.Text) == false)
                        {
                            errorCampo.SetIconAlignment(tbEmail, ErrorIconAlignment.MiddleRight);
                            errorCampo.SetIconPadding(tbEmail, 2);
                            errorCampo.SetError(tbEmail, "Introduce una dirección de email valida");
                        }
                        else
                        {

                            //Comprobar si las coordenadas son validas. Es decir si para el id de usuario
                            //y una contraseña estan ocupadas.
                            if (CADUsuario.Instancia.EstaOcupada(nudBaseX.Value.ToString(), nudBaseY.Value.ToString(), nudCuadX.Value.ToString(), nudCuadY.Value.ToString(), IDusuarioMostrado))
                            {
                                MessageBox.Show("Las coordenadas introducidas ya estan ocupadas por la base de otro usuario", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                            else{
                                ENActividad act = new ENActividad();//Creamos una actividad en la que posteriormente
                                //alamcenaremos los datos de las operaciones realizadas en este menu.
                                ENUsuario nuevo = new ENUsuario();
                                nuevo.IDUsuario = IDusuarioMostrado;
                                nuevo.NombreUsuario = tbNick.Text;
                                nuevo.EmailUsuario = tbEmail.Text;
                                if (tbContrasena.Text != "")
                                {
                                    //Convertir contraseña a MD5
                                    CodMD5 codificar = new CodMD5();
                                    string passmd5 = codificar.convertiraMD5(tbContrasena.Text);
                                    nuevo.PassUsuario = passmd5;
                                }
                                else
                                {
                                    nuevo.PassUsuario = PassUsuarioMostrado;
                                }
                                nuevo.FechaRegUsuario = Convert.ToDateTime(dtpFechaRegistro.Value);
                                nuevo.CXBaseUsuario = Convert.ToInt32(nudBaseX.Value);
                                nuevo.CYBaseUsuario = Convert.ToInt32(nudBaseY.Value);
                                nuevo.CXCuadranteUsuario = Convert.ToInt32(nudCuadX.Value);
                                nuevo.CYCuadranteUsuario = Convert.ToInt32(nudCuadY.Value);


                                if (CADUsuario.Instancia.InsertarUsuario(nuevo))//Caso en el que se trata de un nuevo usuario que se añade.
                                {
                                    // Copio la imagen a un directorio del programa si hay alguna seleccionada
                                    // Sino el usuario se creará sin avatar.
                                    if (imagenCargada == true)
                                    {

                                        string origen = pbAvatar.ImageLocation;
                                        string destino = Application.ExecutablePath;
                                        destino = destino.Remove(destino.LastIndexOf(@"\bin\"));
                                        destino += @"\imagenes\usuarios";
                                        destino += @"\" + tbNick.Text + ".png";

                                        File.Copy(origen, destino);
                                        imagenCargada = false;//Restablecemos la variable para el control de carga de la imagen.
                                    }
                                    formularioUsuarios.Instancia.RellenaDGV();//Actualizamos el dgv con los usuarios.
                                    MessageBox.Show("Usuario creado correctamente", "Información", MessageBoxButtons.OK, MessageBoxIcon.Information);


                                    act.Accion = "Alta";
                                    act.Responsable = formularioMaestro.Instancia.UsuarioLogueado.CuentaAd;
                                    act.Descripcion = "Ha dado de alta al nuevo usuario "+ nuevo.NombreUsuario + ".";
                                    act.Fecha = DateTime.Now.ToString();

                                    CADActividad.Instancia.InsertarActividad(act);
                                    tbNick.Enabled = false;
                                }
                                else//Se trata de una modificación.
                                {
                                    //Modificar la imagen. 
                                    //Caso 1. El usuario ya tenia una imagen pero quiere reemplazarla)
                                    if (imagenCargada == true)
                                    {
                                        //Tengo que borrar primero la imagen por si ya tuviera.
                                        string destino = Application.ExecutablePath;
                                        destino = destino.Remove(destino.LastIndexOf(@"\bin\"));
                                        destino += @"\imagenes\usuarios";
                                        destino += @"\" + nuevo.NombreUsuario + ".png";

                                        /*
                                        pbAvatar.ImageLocation = "";
                                        //pbAvatar.Image.Dispose();
                                        pbAvatar.Image = null;
                                        */

                                        //Podria recorrer dgvusuarios e eliminar la imagen que corresponde al usuario con ese
                                        //id
                                        formularioUsuarios.Instancia.LiberarImagenDeUsuario(nuevo.IDUsuario);

                                        System.GC.Collect();
                                        System.GC.WaitForPendingFinalizers();

                                        File.Delete(destino);//Borramos la imagen

                                        string origen = pbAvatar.ImageLocation;
                                        destino = Application.ExecutablePath;
                                        destino = destino.Remove(destino.LastIndexOf(@"\bin\"));
                                        destino += @"\imagenes\usuarios";
                                        destino += @"\" + tbNick.Text + ".png";

                                        File.Copy(origen, destino);

                                        //Actualizamos el dgv.
                                        formularioUsuarios.Instancia.ActualizarImagenUsuario(nuevo.IDUsuario);
                                        imagenCargada = false;//Restablecemos la variable para el control de carga de la imagen.
                                    }
                                    act.Accion = "Modificación";
                                    act.Responsable = formularioMaestro.Instancia.UsuarioLogueado.CuentaAd;
                                    act.Descripcion = "Ha modificado el usuario " + tbNick.Text + ".";
                                    act.Fecha = DateTime.Now.ToString();

                                    CADActividad.Instancia.InsertarActividad(act);
                                }
                                
                            }
                        }
                    }
                }
            }

        }

        /// <summary>
        /// Modifica y añade edificios del usuario
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btGuardarEdificios_Click(object sender, EventArgs e)
        {
            //Controlar que IDUsuarioMostrado no sea -1 pues estariamos añadiendo uno nuevo
            //y hemos de añadir primero sus datos de usuario.
            if (IDusuarioMostrado == -1)
            {
                MessageBox.Show("Debes introducir y guardar primero los datos del usuario en la ficha cliente", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                tabUsuarios.SelectedIndex = 0;
            }
            else
            {
                ArrayList EdificiosEliminar = new ArrayList(); ;//Lista con los edificios a eliminar.
                ArrayList EdificiosNuevos = new ArrayList();//Lista con los edificios para añadir.
                for (int i = 0; i < dgvEdificios.Rows.Count; i++)
                {
                    EnEdificioUsuario edus = new EnEdificioUsuario();
                    edus.IDEdificio = Convert.ToInt32(dgvEdificios.Rows[i].Cells[5].Value);
                    edus.IDUsuario = IDusuarioMostrado;
                    //Si no se introduce un nivel, el nivel por defecto será cero.
                    edus.NivelEd = Convert.ToInt32(dgvEdificios.Rows[i].Cells[3].Value);
                    if (Convert.ToBoolean(dgvEdificios.Rows[i].Cells[4].Value) == false)
                    {//Para eliminar si es que esta
                        //en los edificios del usuario.
                        EdificiosEliminar.Add(edus);
                    }
                    else
                    {//Para añadir si es que esta en los edificios del usuario.
                        EdificiosNuevos.Add(edus);
                    }
                }
                CADEdificioUsuario.Instancia.DarDeBajaEdificiosUsuario(EdificiosEliminar);
                //MessageBox.Show("Hay " + EdificiosNuevos.Count.ToString() + " edificios para añadir");
                CADEdificioUsuario.Instancia.DarDeAltaEdificiosUsuario(EdificiosNuevos);
                ENUsuario us2 = CADUsuario.Instancia.ObtenerUnUsuario(IDusuarioMostrado);

                //Reportar la actividad.
                ENActividad act = new ENActividad();
                act.Accion = "Modificación";
                act.Responsable = formularioMaestro.Instancia.UsuarioLogueado.CuentaAd;
                act.Descripcion = "Ha modificado edificios del usuario " + us2.NombreUsuario.ToString() + ".";
                act.Fecha = DateTime.Now.ToString();

                CADActividad.Instancia.InsertarActividad(act);
            }
        }

        /// <summary>
        /// Modifica y añade unidades del usuario
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btGuardarUnidades_Click(object sender, EventArgs e)
        {
            //Controlar que IDUsuarioMostrado no sea -1 pues estariamos añadiendo uno nuevo
            //y hemos de añadir primero sus datos de usuario.
            if (IDusuarioMostrado == -1)
            {
                MessageBox.Show("Debes introducir y guardar primero los datos del usuario en la ficha cliente", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                tabUsuarios.SelectedIndex = 0;
            }
            else
            {
                ArrayList UnidadesEliminar = new ArrayList();
                ArrayList UnidadesNuevas = new ArrayList();
                for (int i = 0; i < dgvUnidadesUsuario.Rows.Count; i++)
                {
                    ENUnidadesUsuario unus = new ENUnidadesUsuario();
                    unus.IDUnidad = Convert.ToInt32(dgvUnidadesUsuario.Rows[i].Cells[5].Value);
                    unus.IDUsuario = IDusuarioMostrado;
                    //Si no se especifica cantidad la cantidad por defecto será 1.
                    if (Convert.ToInt32(dgvUnidadesUsuario.Rows[i].Cells[3].Value) == 0)
                    {
                        unus.Cantidad = 1;
                    }
                    else
                    {
                        unus.Cantidad = Convert.ToInt32(dgvUnidadesUsuario.Rows[i].Cells[3].Value);
                    }
                    if (Convert.ToBoolean(dgvUnidadesUsuario.Rows[i].Cells[4].Value) == false)
                    {
                        //Para eliminar, si esque esta en las unidades del usuario
                        UnidadesEliminar.Add(unus);
                    }
                    else
                    {
                        UnidadesNuevas.Add(unus);
                    }
                }
                CADUnidadesUsuario.Instancia.DarDeBajaUnidades(UnidadesEliminar);
                CADUnidadesUsuario.Instancia.DarDeAltaUnidades(UnidadesNuevas);
                ENUsuario us2 = CADUsuario.Instancia.ObtenerUnUsuario(IDusuarioMostrado);

                //Reportar la actividad.
                ENActividad act = new ENActividad();
                act.Accion = "Modificación";
                act.Responsable = formularioMaestro.Instancia.UsuarioLogueado.CuentaAd;
                act.Descripcion = "Ha modificado unidades del usuario " + us2.NombreUsuario.ToString() + ".";
                act.Fecha = DateTime.Now.ToString();

                CADActividad.Instancia.InsertarActividad(act);
            }
    }

        /// <summary>
        /// Esta función me permite borrar el ultimo usuario cuyos datos fueron cargados en el menu.
        /// Aunque se hayan modificado los campos tendra en cuenta la id del usuario.
        /// </summary>
        public void EliminarUsuarioActual()
        {
            if (IDusuarioMostrado != -1)
            {
                ENUsuario us1 = CADUsuario.Instancia.ObtenerUnUsuario(IDusuarioMostrado);//Obtiene los datos del usuario cargado actual.
                if (MessageBox.Show("¿Desea eliminar el usuario " + us1.NombreUsuario + "?", "Información", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
                {
                    string destino = Application.ExecutablePath;
                    destino = destino.Remove(destino.LastIndexOf(@"\bin\"));
                    destino += @"\imagenes\usuarios";
                    destino += @"\" + us1.NombreUsuario + ".png";

                    pbAvatar.ImageLocation = "";
                    pbAvatar.Image.Dispose();
                    pbAvatar.Image = null;

                    System.GC.Collect();
                    System.GC.WaitForPendingFinalizers();

                    ENActividad act = new ENActividad();
                    act.Accion = "Baja";
                    act.Responsable = formularioMaestro.Instancia.UsuarioLogueado.CuentaAd;
                    act.Descripcion = "Ha dado de baja el usuario " + tbNick.Text + ".";
                    act.Fecha = DateTime.Now.ToString();
                    CADActividad.Instancia.InsertarActividad(act);

                    //Eliminamos el usuario y todos sus edificios y unidades.
                    CADUsuario.Instancia.EliminarUsuario(IDusuarioMostrado);
                    //Actualizamos la lista de usuarios y mostramos uno.
                    formularioUsuarios.Instancia.RellenaDGV();

                    System.GC.Collect();
                    System.GC.WaitForPendingFinalizers();

                    File.Delete(destino);//Borramos la imagen
                }
            }
            else
            {
                MessageBox.Show("Debe seleccionar algún usuario primero.", "Información", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button2);
            }
        }

        /// <summary>
        /// Permite seleccionar una imagen para el avatar y cargarla en el pbAvatar
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btBuscarImagen_Click(object sender, EventArgs e)
        {
            //Tendriamos primero que comprobar que hemos introducido el nombre del usuario.

            OpenFileDialog imagen = new OpenFileDialog();
            imagen.Filter = "png (*.png)|*.png";
            pbAvatar.SizeMode = PictureBoxSizeMode.StretchImage;

            if (imagen.ShowDialog() == DialogResult.OK)
            {
                imagenCargada = true;
                string origen = imagen.FileName;
                //File.Copy(origen, destino);

                pbAvatar.ImageLocation = origen;
                //pbAvatar.Image = System.Drawing.Image.FromFile(imagen.FileName);
                //Podemos indicar mediante una variable que la imagen esta selecionada para controlar
                //posibles errores.
            }
        }

        /// <summary>
        /// Función que dado una cadena que contiene una dirección de email me dice si es una
        /// dirección correcta.
        /// </summary>
        /// <param name="correo"> Cadena que contiene el emial</param>
        /// <returns> Devuelve true si se trata de una direccion de email valida</returns>
        bool EmailEsValido(string correo)
        {
            return Regex.IsMatch(correo, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
        }
        /// <summary>
        /// Lo uso para desctivar el campo tbNick para cuando seleccione
        /// un usuario en el DGV
        /// </summary>
        public void DesactivarTBNick()
        {
            tbNick.Enabled = false;
        }
    }
}
